package com.lyl.mallcloud.controller;

/**
 * @Author: Liyunlong
 * @Date: 2024/05/10/19:25
 * @Description:
 */

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.lang.UUID;
import com.lyl.mallcloud.mapper.AdminMapper;
import com.lyl.mallcloud.pojo.Admin;
import com.lyl.mallcloud.pojo.LoginDto;
import com.lyl.mallcloud.pojo.Result;
import com.lyl.mallcloud.service.IAdminService;
import com.lyl.mallcloud.utils.JwtUtil;
import com.lyl.mallcloud.utils.Md5Util;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class UserController {

    @Autowired
    private IAdminService adminService;

    @Autowired
    private AdminMapper adminMapper;
    private LineCaptcha lineCaptcha;
    @Value("${auth.code}")
    private String AUTH_CODE;
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    private static final String USER_ONLINE = "user:oline";

    /***
     * @Description: 管理员注册
     * @Author: Liyunlong
     * @Date: 2024/5/11
     */
    @PostMapping("/register")
    public Result register(@RequestBody LoginDto loginDto) {
        String code = loginDto.getCode();
        String username = loginDto.getUsername();
        String password = loginDto.getPassword();

        if (username.equals("") || password.equals("")) {
            return Result.error("用户名密码不能为空");
        }
        Admin admin = adminService.findByUsername(username);
        if (admin != null) {
            return  Result.error("该用户名已被占用");
        }
        if (!code.equals(AUTH_CODE)) {
            return  Result.error("授权码有误");
        }
        String salt = UUID.randomUUID(true).toString();
        password = Md5Util.getMD5String(password + salt);
        Admin admin2 = new Admin();
        admin2.setUsername(username);
        admin2.setPassword(password);
        admin2.setSalt(salt);
        adminService.save(admin2);
        log.info("管理员注册成功：{}", username);
        return Result.success(admin2);
    }
    /***
     * @Description: 登录的逻辑 Shiro框架
     * @Author: Liyunlong
     * @Date: 2024/5/11
     */
    @PostMapping( "/login")
    public Result login(@RequestBody LoginDto loginDto) {
        String username = loginDto.getUsername();
        String password = loginDto.getPassword();
        String code = loginDto.getCode();
        try {
            if (code == null || (!code.equals(lineCaptcha.getCode()))) {
                log.info("验证码错误");
                return  Result.error("验证码错误");
            }
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            subject.login(usernamePasswordToken);

            Admin byUsername = adminService.findByUsername(username);
            Integer id = byUsername.getId();
            redisTemplate.opsForSet().add(USER_ONLINE, id);
            redisTemplate.expire(USER_ONLINE, 30, TimeUnit.MINUTES);
            log.info("登录成功");
            LoginDto loginDto1 = new LoginDto();
            loginDto1.setUsername(byUsername.getUsername());

            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", byUsername.getId());
            claims.put("username", byUsername.getUsername());
            String token = JwtUtil.createJWT("liyunlong", 60000*30, claims);
            byUsername.setToken(token);
            stringRedisTemplate.opsForValue().set("token:"+byUsername.getId(),token,60000*30, TimeUnit.MINUTES);
            return Result.success(byUsername);
        } catch (UnknownAccountException uae) {
            log.info("用户不存在");
         return  Result.error("用户不存在");
            // 处理账户不存在的情况
        } catch (IncorrectCredentialsException ice) {
            log.info("密码错误");
            // 处理密码不匹配的情况
            return Result.error("密码错误");
        } catch (AuthenticationException ae) {
            // 其他未处理的认证异常
           return Result.error(null);
        }
    }

    @GetMapping("/adminInfo")
    public Result adminInfo(@RequestParam(value = "id") Long id) {
        Admin admin = adminMapper.selectById(id);
        return Result.success(admin);
    }
    /***
     * @Description: 验证码
     * @Author: Liyunlong
     * @Date: 2024/5/11
     */
    @RequestMapping("/getCode")
    public void getCode(HttpServletResponse response) {
        // 随机生成 4 位验证码
        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 5);
        // 定义图片的显示大小
        lineCaptcha = CaptchaUtil.createLineCaptcha(100, 30);
        response.setContentType("image/jpeg");
        response.setHeader("Pragma", "No-cache");
        try {
            lineCaptcha.setGenerator(randomGenerator);
            lineCaptcha.write(response.getOutputStream());
            log.info("生成的验证码:{}", lineCaptcha.getCode());
            response.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}



